<?php
/**
 * 用户模块api
 * Created by PhpStorm.
 * User: liujianlin
 * Date: 2017/5/16
 * Time: 14:18
 */

namespace app\controllers;

use Yii;
use yii\web\Controller;
use yii\web\Response;
use app\components\api\ApiUser;
use app\components\redis\RedisLock;
use app\components\redis\RedisMarketingEmail;
use app\components\mq\MqComponent;
use app\models\Elog;
use app\models\marketing\User;
use app\components\Site;
use app\components\msgcenter\MsgCenter;
use app\models\marketing\MailAutoCreateMonitor;

use yii\mongodb\Query;
use yii\mongodb\ActiveRecord;

class ApiUserController extends Controller
{
    public $enableCsrfValidation = false; // API关闭CSRF验证
    /**
     * redis连接
     * @var RedisMarketingEmail
     */
    private $redis;

    private $userDataToMongoSite = [
        19
    ];

    /**
     * app\models\marketing\User
     * @var User
     */
    private $userModel;

    /**
     * ApiUserController constructor.
     * @param $id
     * @param $module
     * @param array $config
     */
    public function __construct($id, $module, $config = [])
    {
        Yii::$app->response->format = Response::FORMAT_JSON;
        parent::__construct($id, $module, $config);
        set_time_limit(0);
        $this->redis = new RedisMarketingEmail();
        $this->userModel = New User();
    }
    
    
    /**
     * 清空键值
     */
    public function actionDelGbSoaEverydayUsersProgressNums()
    {
        $this->redis->set('gb_soa_everyday_users_progress_nums',0,300);
    }
    
    /**
     * 从mq中消费注销的用户，电子的
     */
    public function actionSynDelUserRabbitmq()
    {
        set_time_limit(60);
        $api = new ApiUser();
        MqComponent::receiveQueueData('QUEUE_EMP_MEMBER_DEL_USER',$api,'userGbSoaDel');
    }

    /**
     * 注销用户，服装站点的
     */
    public function actionSynDelUser()
    {
        $apiUserModel = new ApiUser();
        $postDataFromWeb = Yii::$app->request->post();
        //服装和电子传的参数格式不一致
        if(isset($postDataFromWeb['site']) && 'gearbest' === $postDataFromWeb['site']){
            $postData = $postDataFromWeb;
            $postData['data'] = json_decode($postData['data'],true,512,JSON_BIGINT_AS_STRING);
        }else{
        $postData = array_flip($postDataFromWeb);
        $postData = json_decode(array_pop($postData),true);
        }
        //先验证 api_token
        if(empty($postData['data']['api_token'])){
            return [
                'retCode'=> -1 ,
                'retMsg'=>'API_TOKEN 不存在',
                'retData'=>$postData,
            ];
        }
        $siteName = Yii::$app->params['sites']['marketing_email']['web_index'];
        if(!in_array($postData['site'],$siteName)){
            return [
                'retCode'=> -4 ,
                'retMsg'=>'站点不存在',
                'retData'=>$postData,
            ];
        }

        //从配置文件拿接口地址
        $apiUrl = Yii::$app->params['verify_api_token'][$postData['site']];

        if('gearbest' === $postData['site']){
            $postArr = [
                'header'=>[
                  'service'=>'com.globalegrow.mmember.spi.inter.IMemCommonInnerService',
                    'method'=>'validToken',
                    'domain'=>'',
                    'version'=>'1.0.0',
                    'tokenId'=>Yii::$app->params['verify_api_token_token_id'],
                ],
                'body'=>[
                    'siteCode'=>'GB',
                    'token'=>$postData['data']['api_token'],
                ],
            ];
        }else{
        $postArr = [
            "system" => 'emp',
            "api_token" => $postData['data']['api_token'],
        ];
        }

        // 验证 API_TOKEN
        $item['url'] = $apiUrl;
        $item['options'][CURLOPT_POST] = 1;
        $item['options'][CURLOPT_RETURNTRANSFER] = 1;
        $item['options'][CURLOPT_TIMEOUT] = 300;

        if('gearbest' === $postData['site']){
            $item['options'][CURLOPT_POSTFIELDS] = json_encode($postArr);
            $item['options'][CURLOPT_HTTPHEADER] = array('Content-Type:application/json');
        }else{
            $item['options'][CURLOPT_POSTFIELDS] = $postArr;
        }

        $result = yii::$app->curl->execute($item);

        if('gearbest' === $postData['site']){
            $apiTokenVerify = json_decode($result,true);
            if(empty($apiTokenVerify) || $apiTokenVerify['header']['code'] != 0){
                return [
                    'retCode'=> -2,
                    'retMsg'=>'API_TOKEN 验证不通过',
                    'retData'=>$result,
                ];
            }
        }else{
        $apiTokenVerify = json_decode(urldecode($result), true);
        if(empty($apiTokenVerify) || $apiTokenVerify['errorNo'] != 0){
            return [
              'retCode'=> -2,
              'retMsg'=>'API_TOKEN 验证不通过',
              'retData'=>$postData,
            ];
        }
        }

        $sql = 'select user_id,email,site_user_id from user_'.$postData['site'].' where site_user_id = :site_user_id';
        $userinfo = Yii::$app->db->createCommand($sql)->bindValues([':site_user_id'=>$postData['data']['user_id']])->queryOne();
        if(empty($userinfo)){
            return [
                'retCode'=> 0,
                'retMsg'=>'Success',
                'retData'=>'用户不存在',
            ];
        }
        $trans = Yii::$app->db->beginTransaction();
        try{
            //注销用户，将敏感信息全部删除
            //用户表
            $sql = 'delete from user_'.$postData['site'].' where user_id = :user_id';
            Yii::$app->db->createCommand($sql)->bindValues([':user_id'=>$userinfo['user_id']])->execute();

            //sendlist 表
            $sql = 'delete from mail_sendlist_'.$postData['site'].' where user_id = :user_id';
            Yii::$app->db->createCommand($sql)->bindValues([':user_id'=>$userinfo['user_id']])->execute();

            $sql = 'delete from user_'.$postData['site'].'_goods_data where site_user_id = :site_user_id';
            Yii::$app->db->createCommand($sql)->bindValues([':site_user_id'=>$userinfo['site_user_id']])->execute();
            $trans->commit();
        }catch (\Exception $exception){
           $trans->rollBack();
            Elog::log('user',null,'用户信息注销失败||网站发送的数据：'.\GuzzleHttp\json_encode($postDataFromWeb).' ||错误信息：'.$exception->getMessage(),'error');
            return [
                'retCode'=> -10,
                'retMsg'=>'用户信息注销失败',
                'retData'=>[
                    'user_id'=>$postData,
                ],
            ];
        }
        Elog::log('user',null,'用户信息注销到成功||网站发送的数据：'.\GuzzleHttp\json_encode($postDataFromWeb),'info');
        return [
            'retCode'=> 0,
            'retMsg'=>'Success',
            'retData'=>[
                'user_id'=>$postData['data']['user_id'],
            ],
        ];
    }

    /**
     * 从mq中消费用户数据到
     */
    public function actionSynUserRabbitmq()
    {
        set_time_limit(60);
        $api = new ApiUser();
        MqComponent::receiveQueueData('QUEUE_SYN_MEMBER_DATA_TO_EMP',$api,'userGbSoaEveryday');
        
    }

    /**
     * @TODO:测试数据存储
     */
    public function testSynUser()
    {
        $result = $this->userModel->getGearbestData();
        return $result;
    }
    /**
     * api-user/syn-user
     * 同步用户数据
     */
    public function actionSynUser()
    {
        ini_set('memory_limit', '1024M');
        $post = Yii::$app->request->post();
        $startTime = time();

        if (!isset($post['token'], $post['data'], $post['site_name'])) {
            return ['code' => 10003, 'msg' => '数据不完整'];
        }
        
        $apiToken = yii::$app->params['marketingApiToken'];
        $token = md5($apiToken . $post['data']);
        if ($token != $post['token']) {
            return ['code' => 10001, 'msg' => '令牌错误'];
        }

        //添加同一站点文件锁定
        $redis = $this->redis;
        $redisLock = new RedisLock($redis, "{$post['site_name']}", 300);//同一网站两次同步数据请求间隔需大于5分钟
        if ($redisLock->translock() === false) {
            $msg = "{$post['site_name']} 有请求在处理中，拒绝该次请求！";
            $this->writeLog($msg);
            return ['code' => 10001, 'msg' => $msg];
        }

        $data = json_decode(urldecode($post['data']), true);
        $this->writeLog("{$post['site_name']}同步订阅用户开始,数据总数：".count($data));

        $api = new ApiUser();
        $siteName = $post['site_name'];
        $siteObj = new Site();
        $siteShortName = $siteObj->getSiteShortName($siteName);
        $siteId = $siteObj->getSiteId($siteName);
        if (false == $siteShortName || 0 == $siteId) {
            return ['code' => 10008, 'msg' => '不支持该站点'];
        }

        // 如果存在group_id和sendlist_id的记录就更新,否则就插入
        try {
            $mongoData = ['data'=>$data,'type'=>4,'site'=>$siteShortName,'create_time'=>time()];
            Yii::$app->mongodb->getCollection('post_data_'.$siteShortName)->insert($mongoData);
        } catch (\Exception $e) {
            $this->writeLog( $e->getMessage().'第三方数据存入mongodb失败，失败数据'.json_encode($post['data']));
        }

        if(isset($post['site_sync_situation']) && in_array($siteId, $this->userDataToMongoSite)) {
            $siteSyncSituation = json_decode(urldecode($post['site_sync_situation']), true);
            $result = $api->userMongo($siteShortName, $data, $siteId, $siteSyncSituation);
        } else {
        $result = $api->user($siteShortName, $data, $siteId);
        }

        $errorCount = $result['data']['fail']['count'];
        $endTime = time();
        $this->writeLog("{$post['site_name']}数据保存到redis结束, 失败个数： $errorCount,耗时".($endTime - $startTime)."秒");
        if ($errorCount>=1 && isset($result['data']['failReason'])) {     // 记录失败信息
            $this->writeLog("{$post['site_name']}数据保存到redis结束，失败数据：" . json_encode($result['data']['failReason']));
        }
        $redisLock->unlock();

        return $result;
    }

    /*
     * 定时统计修复用户数据同步日志信息
     * 定时任务2小时运行一次
     */
    public function actionStatisticsUserSyncData()
    {
        set_time_limit(0);

        $getSql = "select * from site_sync_users_log where real_receive_nums = 0 and sync_state = 0 and sync_time > 0 limit 5";

        $userLogs = Yii::$app->db->createCommand($getSql)->queryAll();

        $siteObj = new Site();
        foreach($userLogs as $userLog) {

            $siteId = $userLog['site_id'];
            $addTime = $userLog['sync_time'];

            $siteName = $siteObj->getSiteShortNameById($siteId);
            // 按指定时间获取所有注册用户数
            $allRegistUsersSql = "select count(user_id) nums from user_$siteName where add_date <= $addTime";
            $allRegistUsers = Yii::$app->db->createCommand($allRegistUsersSql)->queryScalar();

             $allLoginUsersSql = "select count(user_id) nums from user_$siteName where last_login > 0 and add_date <= $addTime";
            $allLoginUsers = Yii::$app->db->createCommand($allLoginUsersSql)->queryScalar();

             $allSubscribeUsersSql = "select count(user_id) nums from user_$siteName where is_received_promo = 1 and add_date <= $addTime";
            $allSubscribeUsers = Yii::$app->db->createCommand($allSubscribeUsersSql)->queryScalar();

             $allOrderUsersSql = "select count(user_id) nums from user_$siteName where last_order_time >0 and add_date <= $addTime";
            $allOrderUsers = Yii::$app->db->createCommand($allOrderUsersSql)->queryScalar();

            $realReceiveNums = $userLog['emp_receive_nums']-$userLog['filter_nums'];
            $syncState = 0;
            if($realReceiveNums == $userLog['emp_receive_nums']) {
                $syncState = 1;
            } else if($realReceiveNums < $userLog['emp_receive_nums'] && $realReceiveNums > 0) {
                $syncState = 2;
            } else if($realReceiveNums == 0) {
                $syncState = 3;
            }

            $updateSql = "update site_sync_users_log set real_receive_nums = $realReceiveNums, sync_state = $syncState, emp_all_register_nums=$allRegistUsers, emp_all_login_nums=$allLoginUsers, emp_all_subscribe_nums=$allSubscribeUsers, emp_all_order_nums=$allOrderUsers where id = {$userLog['id']}";
            Yii::$app->db->createCommand($updateSql)->execute();
        }
    }


    /*
     * api-user/monitor-site-syn-user?module_name=marketing_email
     * 定时从redis获取每个网站同步用户数据时间，判断是否超过4小时，并告警
     * 定时任务每小时运行一次
     * @author liugang
     */
    public function actionMonitorSiteSynUser()
    {
        $webIndex = yii::$app->params['sites']['marketing_email']['web_index'];
        $msgCenter = new MsgCenter();
        $curTime = time();
        
        foreach($webIndex as $siteId => $siteName) {
            
            if($siteId == '26' || $siteId == '27' || $siteId == '1' || $siteId == '9' || $siteId == '18') { // 取消nastydress,zanbase和zanstyle站点告警
                continue;
            }
            
            $key = "user_data_sync_time";
//            $this->redis->hset($key, $siteName, yii::$app->bjTime->time()-10);
            $userSynTime = $this->redis->hget($key, $siteName);
//            $userSynTime = '1524110400';
            if($userSynTime !== null) {
                if(($curTime-$userSynTime) > 4*60*60) {
                    
                    $dealData['site_id'] = 99; // 发送人员为EMP所属人员
                    $dealData['title'] = "【{$siteName}】网站未同步用户数据至EMP";
                    $dealData['exceptionEmailTemplateContent'] = "【EMP】异常提示【网站未同步用户数据】：【{$siteName}】网站超过4小时未同步用户数据至EMP，上一次同步时间是【".yii::$app->bjTime->date('Y-m-d H:i',$userSynTime)."】";

                    $dealData['exceptionWechatTemplateContent'] = $dealData['exceptionEmailTemplateContent'];
                    $msgCenter->go_msgcenter($dealData);
                    
                }
            }
        }
    }
    
    /**
     * api-user/post-syn-user-to-save?module_name=marketing_email
     * @TODO:请求actionSynUserToSave接口将临时数据从redis LIST 表，更新到数据库
     * @desc:定时任务每5分钟执行一次
     * @author:eaglezhao
     * @date:2018-03-09
     */
    public function actionPostSynUserToSave()
    {
        $siteObj = new Site();
        $siteInfo = $siteObj->getSiteAllInfo();
        foreach ($siteInfo as $k=>$v) {
            $siteShortName = $v['site_short_name'];
            $url = "http://{$_SERVER['HTTP_HOST']}/api-user/syn-user-to-save"
                . "?module_name=marketing_email&site_short_name={$siteShortName}&site_id={$v['site_id']}";
            $item['url'] = $url;
            $item['options'][CURLOPT_POST] = 0;

            $item['options'][CURLOPT_RETURNTRANSFER] = 1;
            $item['options'][CURLOPT_TIMEOUT] = 1;
            $ret[] = yii::$app->curl->execute($item);
        }
        return $ret;
    }

    /**
     * 把 ems:marketing_email::userInfoList:$sitename:lastSentTime 这个队列
     * 跑到 ems:marketing_email::userInfoList:$sitename 里面去消费，这样做的目的是为了控制最后发送时间的更新时间，可以在指定的时间去更新这个最后发送时间
     * @return mixed
     */
    public function actionSyncLastSentTime()
    {
        $get = Yii::$app->request->get();
        $siteName = isset($get['sitename'])?strtolower($get['sitename']):'';
        $siteNames = Yii::$app->params['sites']['marketing_email']['web_index'];
        if(!empty($siteName) && !in_array($siteName,$siteNames)){
            $this->writeLog("sitename参数错误");
            return ["code"=>10000,"msg"=>"sitename参数错误;get数据".json_encode($get)];
        }
        //没有指定站点，则随机来选择一个站点
        if(empty($siteName)){
            shuffle($siteNames);
            $siteName = array_pop($siteNames);
        }
        var_dump($siteName);
        $listKey = Yii::$app->params['userInfoListKey'].":".$siteName;
        $key = Yii::$app->params['userInfoListKey'].":".strtolower($siteName).":lastSentTime";
        //把最后发送时间的数据放到主的队列里面去供消费
        while (true){
            $result = $this->redis->rpoplpush($key,$listKey);
            if(null === $result){
                break;
            }
        }
    }
    /**
     * api-user/syn-user-to-save
     * @TODO:将临时数据从redis LIST 表，更新到数据库
     * @desc:定时任务每3分钟执行一次，每个站点单进程执行
     * @author:eaglezhao
     * @date:2018-02-21
     */
    public function actionSynUserToSave()
    {
        $leftTime = 180;
        $maxTime = 170;
        set_time_limit($leftTime);
        ini_set('memory_limit', '1024M');
        $startTime = time();

        $get = Yii::$app->request->get();
        $siteShortName = strtolower($get['site_short_name']);
        $siteId = intval($get['site_id']);
        if($siteShortName == ''){
            $this->writeLog("site_short_name参数不能为空;get数据".json_encode($get));
            return ["code"=>10000,"msg"=>"site_short_name参数不能为空;get数据".json_encode($get)];
        }

        $redis = $this->redis;
        $lockKey = "listPopLockKey:".$siteShortName;
        $redisLock = new RedisLock($redis, $lockKey, $leftTime);//最长时间3分钟
        if ($redisLock->translock() === false) {
            $msg = "$siteShortName redis消费队列，有请求正在处理中，拒绝此次请求！";
            $this->writeLog($msg);
            return ['code' => 10001, 'msg' => $msg];
        }

        // 处理写入用户数据到mongo的站
        if(in_array($siteId, $this->userDataToMongoSite)) {
            $insertCount = 0;
            $updateCount = 0;
            $loginCount = 0;
            $orderCount = 0;
            $failCount = $writeMysqlFailCount = $subscribeCount = 0;
            $failReason = [];

            $query = new Query;
            $userDataPatchId = $query->from('post_user_data_' . $siteShortName)->min('user_data_patch_id');
            $usersArr = $query->from('post_user_data_' . $siteShortName)->select([])->where(['user_data_patch_id' => $userDataPatchId])->all();

            if($userDataPatchId && $usersArr) {
                foreach($usersArr as $data) {
                    try{
                        $result = $this->userModel->saveData($siteShortName, $data);
                        if ($result['code'] === 0) {
                            $insertCount += isset($result['insert'])?$result['insert']:0;
                            $updateCount += isset($result['update'])?$result['update']:0;
                            $loginCount += isset($result['login'])?$result['login']:0;
                            $orderCount += isset($result['order'])?$result['order']:0;
                            $subscribeCount += isset($result['subscribe'])?$result['subscribe']:0;
                        } else {
                            $failCount += 1;
                        }
                    } catch(\Exception $e) {
                        $failCount += 1;
                        $failReason[] = ['email' => $data['email'], "reason" => $e->getMessage()];
                    }
                }

                // 更新表数据
                $updateData = [
                    'filter_nums' => $failCount,
                    'sync_date' => yii::$app->bjTime->date('Y-m-d', yii::$app->bjTime->time()),
                    'sync_time' => yii::$app->bjTime->time(),
                    'emp_added_register_nums' => $insertCount,
                    'emp_added_login_nums' => $loginCount,
                    'emp_added_subscribe_nums' => $subscribeCount,
                    'emp_added_order_nums' => $orderCount,
                ];

                $this->userModel->updateSynUsersLogData($updateData, $userDataPatchId);

                // 对数据写入数据库失败进行记录并告警
                // 获取当前站点是否开启告警
                $mailAutoCreateMonitor = new MailAutoCreateMonitor();
                $monitorInfo = $mailAutoCreateMonitor->getSiteSendUsersConfigInfoBySiteid($siteId);

                $synUserLogInfo = $this->userModel->getSynUsersLogData($userDataPatchId);
                $msgCenter = new MsgCenter();

                // 数据入库失败告警
                if($failReason) {
                    $insertArr = [
                        'data_source' => $siteShortName,
                        'source_type' => 1,
                        'monitor_type' => 3,
                        'add_time'   => yii::$app->bjTime->time(),
                        'site_id'    => $siteId,
                        'exception_msg'    => "【EMP】从【{$siteShortName}】所获取的数据在写入至【ems_edm】库下的【user_{$siteShortName}】表时失败。",
                        'error_msg'  => json_encode($failReason)
                    ];
                    $insertId = $this->userModel->insertDataSynMonitorLogData($insertArr);

                    if($monitorInfo && $monitorInfo['state'] == 1) {
                        $dealData = [];
                        $dealData['site_id'] = 99; // 发送人员为EMP所属人员
                        $dealData['title'] = "【{$siteShortName}】数据写入失败";



                        $dealData['exceptionEmailTemplateContent'] = "【EMP】从【{$siteShortName}】所获取的数据在写入至【ems_edm】库下的【user_{$siteShortName}】表时失败。";

                        $dealData['exceptionWechatTemplateContent'] = "【EMP】异常提示【数据写入失败】： 【EMP】从【{$siteShortName}】所获取的数据在写入至【ems_edm】库下的【user_{$siteShortName}】表时失败。";

                        $msgCenter->go_msgcenter($dealData);
                    }

                }
                // emp接收网站推送的新增注册用户数小于大于设置的注册用户平均值
                if($monitorInfo && ($monitorInfo['register_user_min_nums'] > 0 || $monitorInfo['register_user_max_nums'] > 0)) {
                    if($synUserLogInfo['emp_added_register_nums'] < $monitorInfo['register_user_min_nums']) {
                        $insertArr = [
                            'data_source' => $siteShortName,
                            'source_type' => 1,
                            'monitor_type' => 4,
                            'add_time'   => yii::$app->bjTime->time(),
                            'site_id'    => $siteId,
                            'exception_msg'    => "【{$siteShortName}】同步至【EMP】的新增注册用户数为【{$synUserLogInfo['emp_added_register_nums']}】，小于【{$monitorInfo['register_user_min_nums']}】的均值。"
                        ];
                        $insertId = $this->userModel->insertDataSynMonitorLogData($insertArr);

                        if($monitorInfo['state'] == 1) {
                            $dealData = [];
                            $dealData['site_id'] = 99; // 发送人员为EMP所属人员
                            $dealData['title'] = "【{$siteShortName}】同步至【EMP】的新增注册用户数小于均值";



                            $dealData['exceptionEmailTemplateContent'] = "【{$siteShortName}】同步至【EMP】的新增注册用户数为【{$synUserLogInfo['emp_added_register_nums']}】，小于【{$monitorInfo['register_user_min_nums']}】的均值。";

                            $dealData['exceptionWechatTemplateContent'] = "【{$siteShortName}】同步至【EMP】的新增注册用户数为【{$synUserLogInfo['emp_added_register_nums']}】，小于【{$monitorInfo['register_user_min_nums']}】的均值。";

                            $msgCenter->go_msgcenter($dealData);
                        }
                    } else if($synUserLogInfo['emp_added_register_nums'] > $monitorInfo['register_user_max_nums']) {
                        $insertArr = [
                            'data_source' => $siteShortName,
                            'source_type' => 1,
                            'monitor_type' => 4,
                            'add_time'   => yii::$app->bjTime->time(),
                            'site_id'    => $siteId,
                            'exception_msg'    => "【{$siteShortName}】同步至【EMP】的新增注册用户数为【{$synUserLogInfo['emp_added_register_nums']}】，大于【{$monitorInfo['register_user_max_nums']}】的均值。"
                        ];
                        $insertId = $this->userModel->insertDataSynMonitorLogData($insertArr);

                        if($monitorInfo['state'] == 1) {
                            $dealData = [];
                            $dealData['site_id'] = 99; // 发送人员为EMP所属人员
                            $dealData['title'] = "【{$siteShortName}】同步至【EMP】的新增注册用户数大于均值";



                            $dealData['exceptionEmailTemplateContent'] = "【{$siteShortName}】同步至【EMP】的新增注册用户数为【{$synUserLogInfo['emp_added_register_nums']}】，大于【{$monitorInfo['register_user_max_nums']}】的均值。";

                            $dealData['exceptionWechatTemplateContent'] = "【{$siteShortName}】同步至【EMP】的新增注册用户数为【{$synUserLogInfo['emp_added_register_nums']}】，大于【{$monitorInfo['register_user_max_nums']}】的均值。";

                            $msgCenter->go_msgcenter($dealData);
                        }
                    }

                }

                // emp接收网站推送的更新登录用户数小于大于设置的登录用户平均值
                if($monitorInfo && ($monitorInfo['login_user_min_nums'] > 0 || $monitorInfo['login_user_max_nums'] > 0)) {
                    if($synUserLogInfo['emp_added_login_nums'] < $monitorInfo['login_user_min_nums']) {
                        $insertArr = [
                            'data_source' => $siteShortName,
                            'source_type' => 1,
                            'monitor_type' => 4,
                            'add_time'   => yii::$app->bjTime->time(),
                            'site_id'    => $siteId,
                            'exception_msg'    => "【{$siteShortName}】同步至【EMP】的更新登录用户数为【{$synUserLogInfo['emp_added_login_nums']}】，小于【{$monitorInfo['login_user_min_nums']}】的均值。"
                        ];
                        $insertId = $this->userModel->insertDataSynMonitorLogData($insertArr);

                        if($monitorInfo['state'] == 1) {
                            $dealData = [];
                            $dealData['site_id'] = 99; // 发送人员为EMP所属人员
                            $dealData['title'] = "【{$siteShortName}】同步至【EMP】的更新登录用户数小于均值";



                            $dealData['exceptionEmailTemplateContent'] = "【{$siteShortName}】同步至【EMP】的更新登录用户数为【{$synUserLogInfo['emp_added_login_nums']}】，小于【{$monitorInfo['login_user_min_nums']}】的均值。";

                            $dealData['exceptionWechatTemplateContent'] = "【{$siteShortName}】同步至【EMP】的更新登录用户数为【{$synUserLogInfo['emp_added_login_nums']}】，小于【{$monitorInfo['login_user_min_nums']}】的均值。";

                            $msgCenter->go_msgcenter($dealData);
                        }
                    } else if($synUserLogInfo['emp_added_login_nums'] > $monitorInfo['login_user_max_nums']) {
                        $insertArr = [
                            'data_source' => $siteShortName,
                            'source_type' => 1,
                            'monitor_type' => 4,
                            'add_time'   => yii::$app->bjTime->time(),
                            'site_id'    => $siteId,
                            'exception_msg'    => "【{$siteShortName}】同步至【EMP】的更新登录用户数为【{$synUserLogInfo['emp_added_login_nums']}】，大于【{$monitorInfo['login_user_max_nums']}】的均值。"
                        ];
                        $insertId = $this->userModel->insertDataSynMonitorLogData($insertArr);

                        if($monitorInfo['state'] == 1) {
                            $dealData = [];
                            $dealData['site_id'] = 99; // 发送人员为EMP所属人员
                            $dealData['title'] = "【{$siteShortName}】同步至【EMP】的更新登录用户数大于均值";



                            $dealData['exceptionEmailTemplateContent'] = "【{$siteShortName}】同步至【EMP】的更新登录用户数为【{$synUserLogInfo['emp_added_login_nums']}】，大于【{$monitorInfo['login_user_max_nums']}】的均值。";

                            $dealData['exceptionWechatTemplateContent'] = "【{$siteShortName}】同步至【EMP】的更新登录用户数为【{$synUserLogInfo['emp_added_login_nums']}】，大于【{$monitorInfo['login_user_max_nums']}】的均值。";

                            $msgCenter->go_msgcenter($dealData);
                        }
                    }

                }

                // emp接收网站推送的更新订阅用户数小于大于设置的订阅用户平均值
                if($monitorInfo && ($monitorInfo['subscribe_user_min_nums'] > 0 || $monitorInfo['subscribe_user_max_nums'] > 0)) {
                    if($synUserLogInfo['emp_added_subscribe_nums'] < $monitorInfo['subscribe_user_min_nums']) {
                        $insertArr = [
                            'data_source' => $siteShortName,
                            'source_type' => 1,
                            'monitor_type' => 4,
                            'add_time'   => yii::$app->bjTime->time(),
                            'site_id'    => $siteId,
                            'exception_msg'    => "【{$siteShortName}】同步至【EMP】的更新订阅用户数为【{$synUserLogInfo['emp_added_subscribe_nums']}】，小于【{$monitorInfo['subscribe_user_min_nums']}】的均值。"
                        ];
                        $insertId = $this->userModel->insertDataSynMonitorLogData($insertArr);

                        if($monitorInfo['state'] == 1) {
                            $dealData = [];
                            $dealData['site_id'] = 99; // 发送人员为EMP所属人员
                            $dealData['title'] = "【{$siteShortName}】同步至【EMP】的更新订阅用户数小于均值";



                            $dealData['exceptionEmailTemplateContent'] = "【{$siteShortName}】同步至【EMP】的更新订阅用户数为【{$synUserLogInfo['emp_added_subscribe_nums']}】，小于【{$monitorInfo['subscribe_user_min_nums']}】的均值。";

                            $dealData['exceptionWechatTemplateContent'] = "【{$siteShortName}】同步至【EMP】的更新订阅用户数为【{$synUserLogInfo['emp_added_subscribe_nums']}】，小于【{$monitorInfo['subscribe_user_min_nums']}】的均值。";

                            $msgCenter->go_msgcenter($dealData);
                        }
                    } else if($synUserLogInfo['emp_added_subscribe_nums'] > $monitorInfo['subscribe_user_max_nums']) {
                        $insertArr = [
                            'data_source' => $siteShortName,
                            'source_type' => 1,
                            'monitor_type' => 4,
                            'add_time'   => yii::$app->bjTime->time(),
                            'site_id'    => $siteId,
                            'exception_msg'    => "【{$siteShortName}】同步至【EMP】的更新订阅用户数为【{$synUserLogInfo['emp_added_subscribe_nums']}】，大于【{$monitorInfo['subscribe_user_max_nums']}】的均值。"
                        ];
                        $insertId = $this->userModel->insertDataSynMonitorLogData($insertArr);

                        if($monitorInfo['state'] == 1) {
                            $dealData = [];
                            $dealData['site_id'] = 99; // 发送人员为EMP所属人员
                            $dealData['title'] = "【{$siteShortName}】同步至【EMP】的更新订阅用户数大于均值";



                            $dealData['exceptionEmailTemplateContent'] = "【{$siteShortName}】同步至【EMP】的更新订阅用户数为【{$synUserLogInfo['emp_added_subscribe_nums']}】，大于【{$monitorInfo['subscribe_user_max_nums']}】的均值。";

                            $dealData['exceptionWechatTemplateContent'] = "【{$siteShortName}】同步至【EMP】的更新订阅用户数为【{$synUserLogInfo['emp_added_subscribe_nums']}】，大于【{$monitorInfo['subscribe_user_max_nums']}】的均值。";

                            $msgCenter->go_msgcenter($dealData);
                        }
                    }

                }

                // emp接收网站推送的新增注册用户数小于大于设置的注册用户平均值
                if($monitorInfo && ($monitorInfo['order_user_min_nums'] > 0 || $monitorInfo['order_user_max_nums'] > 0)) {
                    if($synUserLogInfo['emp_added_order_nums'] < $monitorInfo['order_user_min_nums']) {
                        $insertArr = [
                            'data_source' => $siteShortName,
                            'source_type' => 1,
                            'monitor_type' => 4,
                            'add_time'   => yii::$app->bjTime->time(),
                            'site_id'    => $siteId,
                            'exception_msg'    => "【{$siteShortName}】同步至【EMP】的更新下单用户数为【{$synUserLogInfo['emp_added_order_nums']}】，小于【{$monitorInfo['order_user_min_nums']}】的均值。"
                        ];
                        $insertId = $this->userModel->insertDataSynMonitorLogData($insertArr);

                        if($monitorInfo['state'] == 1) {
                            $dealData = [];
                            $dealData['site_id'] = 99; // 发送人员为EMP所属人员
                            $dealData['title'] = "【{$siteShortName}】同步至【EMP】的更新下单用户数小于均值";



                            $dealData['exceptionEmailTemplateContent'] = "【{$siteShortName}】同步至【EMP】的更新下单用户数为【{$synUserLogInfo['emp_added_order_nums']}】，小于【{$monitorInfo['order_user_min_nums']}】的均值。";

                            $dealData['exceptionWechatTemplateContent'] = "【{$siteShortName}】同步至【EMP】的更新下单用户数为【{$synUserLogInfo['emp_added_order_nums']}】，小于【{$monitorInfo['order_user_min_nums']}】的均值。";

                            $msgCenter->go_msgcenter($dealData);
                        }
                    } else if($synUserLogInfo['emp_added_order_nums'] > $monitorInfo['order_user_max_nums']) {
                        $insertArr = [
                            'data_source' => $siteShortName,
                            'source_type' => 1,
                            'monitor_type' => 4,
                            'add_time'   => yii::$app->bjTime->time(),
                            'site_id'    => $siteId,
                            'exception_msg'    => "【{$siteShortName}】同步至【EMP】的更新下单用户数为【{$synUserLogInfo['emp_added_order_nums']}】，大于【{$monitorInfo['order_user_max_nums']}】的均值。"
                        ];
                        $insertId = $this->userModel->insertDataSynMonitorLogData($insertArr);

                        if($monitorInfo['state'] == 1) {
                            $dealData = [];
                            $dealData['site_id'] = 99; // 发送人员为EMP所属人员
                            $dealData['title'] = "【{$siteShortName}】同步至【EMP】的更新下单用户数大于均值";

                            $dealData['exceptionEmailTemplateContent'] = "【{$siteShortName}】同步至【EMP】的更新下单用户数为【{$synUserLogInfo['emp_added_order_nums']}】，大于【{$monitorInfo['order_user_max_nums']}】的均值。";

                            $dealData['exceptionWechatTemplateContent'] = "【{$siteShortName}】同步至【EMP】的更新下单用户数为【{$synUserLogInfo['emp_added_order_nums']}】，大于【{$monitorInfo['order_user_max_nums']}】的均值。";

                            $msgCenter->go_msgcenter($dealData);
                        }
                    }

                }

                // 处理完成后删除mongo中的数据
                Yii::$app->mongodb->getCollection('post_user_data_' . $siteShortName)->remove(array('user_data_patch_id' => $userDataPatchId));
            }
        }


        $listKey = Yii::$app->params['userInfoListKey'].":".$siteShortName;
        $importListKey = Yii::$app->params['userInfoImportListKey'].":".$siteShortName;
        $errorMsg = [];
        $insertCount = 0;
        $updateCount = 0;
        $loginCount = 0;
        $orderCount = 0;
        $i = 0;
        $businessName = "";
        while (true) {
            if ((time() - $startTime) >= $maxTime){
                break;
            }
            try {
                $dataJson = $redis->rpop($importListKey);
                if(!$dataJson){
                    $dataJson = $redis->rpop($listKey);
                }
                if (!$dataJson) {
                    break;
                }
                //利用$dataJson进行逻辑和数据处理
                $data = json_decode($dataJson,true);
                if ($data['error_times'] == 0) {
                    $i++ ;
                }
                $type = $data['businessType'];
                switch ($type) {
                    case 1://第三方通道更新数据
                        $result = $this->_synRedisSqlToSave($data);
                        $businessName = "第三方通道更新数据";
                        break;
                    case 2://用户退订数据
                        $result = $this->_synRedisSqlToSave($data);
                        $businessName = "用户退订数据";
                        break;
                    case 3://邮件打开数据
                        $result = $this->_synRedisSqlToSave($data);
                        $businessName = "邮件打开数据";
                        break;
                    case 4://日常用户数据更新
                        $result = $this->_synDaylyUserToSave($data);
                        $businessName = "日常用户数据更新";
                        break;
                    case 5://邮件发送，修改最后发送时间
                        //获取当前的小时数，没有前导零
                        $g = Yii::$app->bjTime->date('G');
                        //晚上9点到早上8点这时间段内不更新发送时间，避免这个时间段对 ES 造成太大压力
                        if($g < 8 || $g > 20){
                            $redis->lpush($listKey,$dataJson);
                            break;
                        }
                        $result = $this->_synRedisSqlToSave($data);
                        $businessName = "邮件发送";
                        break;
                    case 6://导入用户退订数据,后台操作设置用户退订
                        $result = $this->_synRedisSqlToSave($data);
                        $businessName = "导入用户退订";
                        break;
                    case 7://导入用户分群数据
                        $result = $this->_synRedisSqlToSave($data);
                        $businessName = "导入用户分群";
                        break;
                    case 8://导入黑名单/手动添加黑名单/手动取消黑名单
                        $result = $this->_synRedisSqlToSave($data);
                        $businessName = "导入黑名单";
                        break;
                    case 9://后台操作：用户订阅
                        $result = $this->_synRedisSqlToSave($data);
                        $businessName = "用户订阅";
                        break;
                    case 10://后台操作：标识内测用户/取消标识内测用户
                        $result = $this->_synRedisSqlToSave($data);
                        $businessName = "标识内测用户";
                        break;
                    case 11://购物车退订
                        $result = $this->_synRedisSqlToSave($data);
                        $businessName = "购物车退订";
                        break;
                    case 12://导入分群后需要 修改用户分群表数据
                        $result = $this->_synRedisSqlToGroupSave($data);
                        $businessName = "修改用户分群表数据";
                        break;
                    default:
                        $errorMsg[] = ['code' => 10002, "msg"=>"业务类型不正确"];
                }
                if ($result['code'] === 0) {
                    $insertCount += isset($result['insert'])?$result['insert']:0;
                    $updateCount += isset($result['update'])?$result['update']:0;
                    $loginCount += isset($result['login'])?$result['login']:0;
                    $orderCount += isset($result['order'])?$result['order']:0;
                } else {
                    $errorMsg[] = $result;
                }
            } catch (\Exception $e) {
                $errorMsg[] = ['code' => 10003, "msg"=>$e->getMessage()];
            }
        }
        $errorCount = count($errorMsg);
        $endTime = time();
        $spendTime = $endTime - $startTime;
        if ($i > 0) {
            if ($errorCount >= 1) {
                $this->writeLog("站点".$siteShortName." 模块:$businessName 从redis LIST消费数据，共 $i 条，失败数据：" . json_encode($errorMsg)."，花费时间".$spendTime."秒, insert[$insertCount],update[$updateCount],login[$loginCount],order[$orderCount]");
            }else{
                $this->writeLog("站点".$siteShortName." 模块:$businessName 从redis LIST消费数据，共 $i 条，此次全部成功，花费时间".$spendTime."秒, insert[$insertCount],update[$updateCount],login[$loginCount],order[$orderCount]");
            }
        }
        $redisLock->unlock();
        unset($errorMsg);
        $ret = ["code"=>"OK", "msg"=>"执行完毕",'spend_time'=>$spendTime,"siteName"=>$siteShortName];
        exit(json_encode($ret));
    }

    /**
     * @TODO：日常用户数据更新到数据库
     * @params：$redisData redis里存的数据
     * @author：eaglezhao
     * @date:2018-03-12
     */
    private function _synDaylyUserToSave($redisData)
    {
        $siteName = $redisData['site'];
        $data = $redisData['data'];
        $db = Yii::$app->db;
        try {
            $transaction = $db->beginTransaction();
            $retMsg = $this->userModel->saveData($siteName, $data);
            $transaction->commit();
        } catch (\Exception $e) {
            $transaction->rollBack();
            $redisData['error_times'] += 1;
            $errorTimes = $redisData['error_times'];
            $retMsg = ['code' => 10006, 'site'=>$siteName, 'create_time' => $redisData['create_time'],'error_times'=>$errorTimes, "reason" => $e->getMessage()];
            if ($redisData['error_times'] <= 2) {
                $key = yii::$app->params['userInfoListKey'].":".$redisData["site"];
                $this->redis->lpush($key,json_encode($redisData));
            }

        }
        return $retMsg;
    }
    /**
     *@TODO：日常用户数据保存到数据库
     * @params：redis里存的数据
     * @author：eaglezhao
     * @date:2018-02-22
     */
    private function _synDaylyUserToSaveBAK($redisData)
    {
        $redis = $this->redis;
        $db = Yii::$app->db;
        $errorMsg = [];

        if($redisData['operateType'] == 1){//新增数据需要插入
            $table = "user_" . strtolower($redisData["site"]);
            $record = $redisData["data"];
            try {
                $transaction = $db->beginTransaction();
                $retAdd = $this->userModel->addRecord($table, $record);
                $userId = yii::$app->db->getLastInsertID();
                $oldLastOrderTime = $redisData['oldLastOrderTime'];
                $oldLoginTime = $redisData['oldLastLoginTime'];
                $this->_updateOrderAndLogin($oldLastOrderTime,$oldLoginTime,$userId,$redisData);
                $transaction->commit();
            } catch (\Exception $e) {
                //数据库回滚
                $transaction->rollBack();
                //再插回到redis队列
                $redisData['error_times'] += 1;
                $errorTimes = $redisData['error_times'];
                $errorMsg = ['site'=>$redisData["site"], 'email' => $record['email'],'error_times'=>$errorTimes, "reason" => $e->getMessage()];
                if($redisData['error_times'] <= 2){
                    $key = yii::$app->params['userInfoListKey'].":".$redisData["site"];
                    $redis->lpush($key,json_encode($redisData));
                }
            }
        }elseif($redisData['operateType'] == 2){//修改数据
            $table = $table = "user_" . strtolower($redisData["site"]);
            $record = $redisData["data"];
            $userId = $record["site_user_id"];
            $condition = $redisData["condition"];
            try {
                $transaction = $db->beginTransaction();
                $retUpdate = $this->userModel->updateRecord($table, $condition, $record);
                $oldLastOrderTime = $redisData['oldLastOrderTime'];
                $oldLoginTime = $redisData['oldLastLoginTime'];
                $this->_updateOrderAndLogin($oldLastOrderTime,$oldLoginTime,$userId,$redisData);
                $transaction->commit();
            } catch (\Exception $e) {
                //数据库回滚
                $transaction->rollBack();
                //再插回到redis队列
                $redisData['error_times'] += 1;
                $errorTimes = $redisData['error_times'];
                $errorMsg = ['site'=>$redisData["site"], 'email' => $record['email'],'error_times'=>$errorTimes, "reason" => $e->getMessage()];
                if($redisData['error_times'] <= 2){
                    $key = yii::$app->params['userInfoListKey'].":".$redisData["site"];
                    $redis->lpush($key,json_encode($redisData));
                }
            }
        }else{
            $errorMsg = ['msg'=>'操作类型不正确'];
        }
        return $errorMsg;
    }


    /**
     * @TODO:更新订单表和登录表
     * @param $oldLastOrderTime
     * @param $oldLoginTime
     * @param $data
     * @author:eaglezhao
     * @date:2018-02-22
     */
    private function _updateOrderAndLogin($oldLastOrderTime,$oldLoginTime,$userId,$data)
    {
        // 最后下单时间比较新，则在下单时间记录表中添加新记录
        $record = $data['data'];
        if (isset($record['last_order_time']) && $oldLastOrderTime < $record['last_order_time']){
            $this->userModel->addLastOrderRecord($data['site'], $userId, $record);
        }
        // 最后登录时间比较新，则在登录时间记录表中添加新记录
        if (isset($record['last_login']) && $oldLoginTime < $record['last_login']) {
            $this->userModel->addLoginRecord($data['site'], $userId, $record);
        }
    }

    /**
     * @TODO:更新用户表，最后发送时间字段
     * @param $data
     * @author:eaglezhao
     * @date:2018-02-27
     */
    private function _synRedisSqlToSave($data)
    {
        $redis = $this->redis;
        $db = Yii::$app->db;
        try {
            $transaction = $db->beginTransaction();
            $retMsg = $this->userModel->executeRedisSql($data);
            $transaction->commit();
        } catch (\Exception $e) {
            //数据库回滚
            $transaction->rollBack();
            //再插回到redis队列
            $data['error_times'] += 1;
            $errorTimes = $data['error_times'];
            $retMsg = ['code' => 10007,'site'=>$data["site"], 'create_time' => $data['create_time'],'error_times'=>$errorTimes, "reason" => $e->getMessage()];
            if ($data['error_times'] <= 2) {
                $key = yii::$app->params['userInfoListKey'].":".$data["site"];
                $redis->lpush($key,json_encode($data));
            }
        }
        return $retMsg;
    }

    /**
     * 同步用户数据
     */
    public function actionSynUserBAK()
    {
        $post = Yii::$app->request->post();
        if (!isset($post['token'], $post['data'], $post['site_name'])) {
            return ['code' => 10003, 'msg' => '数据不完整'];
        }

        $apiToken = yii::$app->params['marketingApiToken'];
        $token = md5($apiToken . $post['data']);
        if ($token != $post['token']) {
            return ['code' => 10001, 'msg' => '令牌错误'];
        }


        $data = json_decode(urldecode($post['data']), true);
//        var_dump($data);
//        exit();

        $this->writeLog("{$post['site_name']}同步订阅用户开始,数据总数：".count($data));

        $redis = new RedisMarketingEmail();
        //添加同一站点文件锁定
        $redisLock = new RedisLock($redis, "{$post['site_name']}", 300);//同一网站两次同步数据请求间隔需大于5分钟

        if ($redisLock->translock() === false) {
            $msg = "有请求在处理中，拒绝该请求！";
            $this->writeLog($msg);
            return ['code' => 10001, 'msg' => $msg];
        }


//        $this->writeLog("{$post['site_name']}用户数据: " . json_encode($post, true));
        $api = new ApiUser();
        $siteName = $post['site_name'];
        $result = $api->user($siteName, $data);
        if (empty($result['data'])) {
            return $result;
        }
        $resultData = $result['data'];

        $this->writeLog("{$post['site_name']}同步订阅用户结束: insert[{$resultData['insert']['count']}], "
            . "update[{$resultData['update']['count']}], login[{$resultData['login']['count']}], " .
            "order[{$resultData['order']['count']}], fail[{$resultData['fail']['count']}]");
        if (isset($resultData['failReason'])) {     // 记录失败信息
            $this->writeLog("{$post['site_name']}同步订阅用户，失败数据：" . json_encode($resultData['failReason']));
            unset($result['data']['failReason']);
        }
        return $result;
    }

    /**
     * 退订用户数据
     * @return array
     */
    public function actionSynUnsubscribeToWeb()
    {
        $post = Yii::$app->request->post();
        if (!isset($post['token'], $post['data'], $post['site_name'])) {
            return ['code' => 10003, 'msg' => '数据不完整'];
        }

        $apiToken = yii::$app->params['marketingApiToken'];
        $token = md5($apiToken . $post['data']);
        if ($token != $post['token']) {
            return ['code' => 10001, 'msg' => '令牌错误'];
        }

        $data = json_decode(urldecode($post['data']), true);

        $api = new ApiUser();
        $siteName = $post['site_name'];
        $result = $api->unsubscribeToWeb($siteName, $data);
        return $result;
    }

    /**
     *
     * @param $msg
     */
    private function writeLog($msg)
    {
        $date = yii::$app->bjTime->date("Y-m-d H:i:s");
        $today = yii::$app->bjTime->date("Ymd");
        $dir = yii::$app->getRuntimePath() . "/logs/" . yii::$app->bjTime->date("Ym");
        if (!is_dir($dir)) {
            mkdir($dir, 0777, true);
        }
        $filePath = $dir . "/user_{$today}.log";
        $msg = "[{$date}] $msg" . PHP_EOL;
        file_put_contents($filePath, $msg, FILE_APPEND);
    }
    
    /*
     * 清除runtime中的日志文件
     */
    public function actionClearLogs()
    {
        $get = Yii::$app->request->get();
        if(isset($get['retainDays']) && ($retainDays = (int)$get['retainDays']) >0)
        {
                $dir = yii::$app->getRuntimePath() . "/logs/";
                if(is_dir($dir))
                {
                    $result = $this->deleteDir($dir,$retainDays);
                    if($result !== true)
                    {
                        echo $result."删除失败！";
                    }
                }
        }
        echo "done";
    }
    /*
     * 删除目录
     */
    private function deleteDir( $dir = '' ,$retainDays)
    {
        $retainTime = time()-$retainDays*24*60*60;
        $files = scandir( $dir );
        $dirPath = substr( $dir, -1 ) == "/" ? substr( $dir, 0, strlen( $dir ) - 1 ) : $dir;
        foreach( $files as $file )
        {
            if( !in_array( $file, array( ".", ".." ) ) )
            {
                if( is_dir( $dirPath . "/" . $file ) )
                {
                    $result = $this->deleteDir( $dirPath . "/" . $file ,$retainDays);
                    if( !$result )
                    {
                        return $dirPath . "/" . $file;
                    }
                }
                else
                {
                    if(is_file($dirPath . "/" . $file) && filemtime($dirPath . "/" . $file) <= $retainTime)
                    {
                        $result = unlink( $dirPath . "/" . $file );
                        if( !$result )
                        {
                            return $dirPath . "/" . $file;
                        }
                    }
                    
                }

            }
        }
        $isEmpty = 1;
        foreach( $files as $file )
        {
            if( !in_array( $file, array( ".", ".." ) ) )
            {
                if(file_exists($dirPath . "/" . $file))
                {
                    $isEmpty = 0;
                }
            }
        }
        
        if($isEmpty)
        {
            $result = rmdir( $dir );
            if( !$result )
            {
                return $dir;
            }
        }
        
        return true;
    }


    public function _synRedisSqlToGroupSave($data){
        $redis = $this->redis;
        $db = Yii::$app->db;
        try {
            $transaction = $db->beginTransaction();
            $retMsg = $this->userModel->executeRedisGroupSql($data);
            $transaction->commit();
        } catch (\Exception $e) {
            //数据库回滚
            $transaction->rollBack();
            //再插回到redis队列
            $data['error_times'] += 1;
            $errorTimes = $data['error_times'];
            $retMsg = ['code' => 10007,'site'=>$data["site"], 'create_time' => $data['create_time'],'error_times'=>$errorTimes, "reason" => $e->getMessage()];
            if ($data['error_times'] <= 2) {
                $key = yii::$app->params['userInfoListKey'].":".$data["site"];
                $redis->lpush($key,json_encode($data));
            }
        }
        return $retMsg;
    }

}

